package generic1;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

public class GenericTest {

    public static void main(String[] args) {

    }

    //1:泛型在继承方面的提现
    //
    //类A是类B的父类,G<A>和G<B>二者不具备父子类继承关系,二者是完全并列关系

    //补充:类A是类B的父类,A<G>和B<G>是的父类
    @Test
    public void test1(){
        Object obj = null;
        String str = null;

        //因为String继承于Object,所以父类对象可以指向子类对象
        obj = str;

        Object[] arr1 = null;
        String[] arr2 = null;

        arr1 = arr2;

        List<Object> list1 = null;
        List<String> list2 = null;

        //此时list1和list2的类不具备继承关系,是平行关系,所以不能相互赋值
        //编译不通过
        //list1 = list2;
    }

    /*
    * 2:通配符的使用
    * 通配符: ?
    * 类A是类B的父类,G<A>和G<B>没有关系,二者共同的父类是:G<?>
    * */
    @Test
    public void test2(){

        List<Object> list1 = null;
        List<String> list2 = null;

        List<?> list = null;

        list = list1;
        list = list2;


        List<String> list3 = new ArrayList<>();
        list3.add("AA");

        list = list3;

        //使用通配符的List对象,不能执行添加操作
        //list.add("BB");

        //但是有一个例外,可以添加null
        list.add(null);

        //使用通配符的List对象,可以读取数据,读取的数据类型是Object
        Object o = list.get(0);
        System.out.println(o);//AA
    }

    /*
    * 3:有限制条件的通配符
    *
    * ? extends Person
    * ? super Person
    * */
    @Test
    public void test3(){

        //list1只能赋值给包含Person的子类的List类型对象
        List<? extends Person> list1 = null;

        //list2只能赋值给Person的父类或父类的父类的List类型对象
        List<? super Person> list2 = null;

        List<Student> list3 = null;
        List<Person> list4 = null;
        List<Object> list5 = null;

        list1 = list3;
        list1 = list4;
//        list1 = list5;

//        list2 = list3;
        list2 = list4;
        list2 = list5;

        //写入数据
//        编译不通过
//        list1.add(new Student());

        list2.add(new Person());
        list2.add(new Student());
    }
}
